home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
BARNET
/
FREENET
/
MELL
/
NETLIB00
/
NetLib
/
c
/
host
< prev
next >
Wrap
Text File
|
1995-05-25
|
5KB
|
247 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "arpa/inet.h"
#include "netdb.h"
#include "netinet/in.h"
#include "sys/socket.h"
#include "socketlib.h"
/*
* Veneers to the InetDB routines
*/
extern struct hostent *_gethostbyname(const char *name);
extern struct hostent *_gethostbyaddr(const char *addr, int len, int type);
/*
* File handle for the hosts file
*/
static FILE *hostfile = NULL;
/*
* Keep the file open between calls to these routines?
*/
static int keepopen = 0;
/*
* Local routines
*/
static int __sethostent(int allowrewind);
static struct hostent *__gethostent(void);
/*
* Open and rewind the hosts file
*/
int sethostent(int stayopen)
{
/* Record whether the file should be kept open */
keepopen = stayopen;
return __sethostent(1);
}
/*
* Do the real work of opening/rewinding the hosts file
*/
static int __sethostent(int allowrewind)
{
/* Open or rewind the file as necessary */
if (hostfile) {
if (allowrewind)
rewind(hostfile);
} else {
hostfile = fopen("InetDBase:Hosts", "r");
}
return (hostfile == NULL) ? -1 : 0;
}
/*
* Fetch the next entry from the hosts file
*/
struct hostent *gethostent()
{
struct hostent *host;
/* Open the file if necessary */
if (hostfile == NULL)
if (__sethostent(0) == -1)
return NULL;
/* Do the actual read */
host = __gethostent();
/* Close the file unless the user has prohibited it */
if (!keepopen)
endhostent();
return host;
}
/*
* Do the real work of getting an entry from the file
*/
struct hostent *__gethostent()
{
static struct hostent host = {
NULL, NULL, AF_INET, sizeof(struct in_addr), NULL
};
char **item;
char *line;
char *element;
int aliases;
/* Free up any memory in use */
if (host.h_name)
{
for (item = host.h_aliases; *item; item++)
free(*item);
for (item = host.h_addr_list; *item; item++)
free(*item);
free(host.h_name);
free(host.h_aliases);
free(host.h_addr_list);
host.h_name = NULL;
}
/* Read a line from the file */
if ((line = __socketlib_readline(hostfile)) == NULL)
return NULL;
/* Extract the address from the line */
host.h_addr_list = malloc(2 * sizeof(struct in_addr *));
host.h_addr_list[0] = malloc(sizeof(struct in_addr));
host.h_addr_list[1] = NULL;
element = strtok(line, " \t");
((struct in_addr *)(host.h_addr_list[0]))->s_addr = inet_addr(element);
/* Extract the offical hostname from the line */
element = strtok(NULL, " \t");
host.h_name = strdup(element);
/* Initialialise the alias list */
host.h_aliases = malloc(sizeof(char *));
host.h_aliases[0] = NULL;
aliases = 1;
/* Extract the aliases */
while ((element = strtok(NULL, " \t")) != NULL)
{
aliases += 1;
host.h_aliases = realloc(host.h_aliases, aliases * sizeof(char *));
host.h_aliases[aliases-2] = strdup(element);
host.h_aliases[aliases-1] = NULL;
}
return &host;
}
/*
* Close the hosts file
*/
int endhostent()
{
int status = 0;
/* If its open, close it */
if (hostfile) {
status = fclose(hostfile);
hostfile = 0;
}
return status;
}
/*
* Search the hosts file for a given host name
*/
struct hostent *gethostbyname(const char *name)
{
struct hostent *host;
char **alias;
/* Try the resolver first */
if ((host = _gethostbyname(name)) != NULL)
{
return host;
}
/* Open/rewind the file */
if (__sethostent(1) == -1)
return NULL;
/* Look through the file for a match */
while ((host = __gethostent()) != NULL)
{
/* Does the offical name match? */
if (strcmp(host->h_name, name) == 0)
break;
/* Do any of the aliases match? */
for (alias = host->h_aliases; *alias; alias++)
{
if (strcmp(*alias, name) == 0)
break;
}
/* Did any of the aliases match? */
if (*alias)
break;
}
/* Close the file unless the user has prohibited it */
if (!keepopen)
endhostent();
return host;
}
/*
* Search the hosts file for a given address
*/
struct hostent *gethostbyaddr(const char *addr, int len, int type)
{
struct hostent *host;
char **address;
/* Try the resolver first */
if ((host = _gethostbyaddr(addr, len, type)) != NULL)
{
return host;
}
/* Open/rewind the file */
if (__sethostent(1) == -1)
return NULL;
/* Look through the file for a match */
while ((host = __gethostent()) != NULL) {
/* If the type and length don't match, try the next one */
if ((host->h_length != len) || (host->h_addrtype != type))
continue;
/* Do any of the addresses match? */
for (address = host->h_addr_list; *address; address++)
{
if (memcmp(*address, addr, len) == 0)
break;
}
/* Did any of the aliases match? */
if (*address)
break;
}
/* Close the file unless the user has prohibited it */
if (!keepopen)
endhostent();
return host;
}